首先讓我們回到最初的官方範例
https://codesandbox.io/s/basic-demo-rrppl0y8l4
import { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
function Box(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => (ref.current.rotation.x += delta))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
export default function App() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
<pointLight position={[-10, -10, -10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
)
}
先分別放置 hovered 與 clicked 的State
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
然後就可以像一般在 新增事件一樣來使用它
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
</mesh>
接下來,我們要讓櫃子跟抽屜....可。以。打。開。
讓我們修改小抽屜的元件
function MBox({ id, lineH, ...props }) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
const [hoveredContent, hoverContent] = useState(false)
const [clickedContent, clickContent] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => {
return (
<group
{...props}
ref={ref}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}
position={[-1.33, lineH, hovered ? -0.1 : -0.13]}>
<ModelCMDpack
onClicked={clicked && clickedContent}
rotation={[0.4, 0, 0]}
scale={[0.13, 0.13, 0.15]}
position={[-0.01, 0.04 + 0.01, clicked ? 0.5 : 0.21]}
onClick={(event) => {
getSelectBox(`R${id.row}:C${id.col}`, clicked)
}}
/>
<group scale={[0.13, 0.13, 0.45]}>
<group position={[0, 0, clicked ? 0.8 - 0.35 : -0.13]}>
<mesh scale={[1, 1, 1 / 2]} onClick={(event) => click(!clicked)} position={[-0.01, -0.13, 1.01 - 0.05]}>
<boxGeometry args={[1, 1 * 0.5, 0.5]} />
<meshStandardMaterial transparent opacity={0.01} color={hovered ? 'hotpink' : 'orange'} />
</mesh>
<mesh
onPointerOver={(event) => hoverContent(true)}
onPointerOut={(event) => hoverContent(false)}
onClick={(event) => {
clickContent(!clickedContent)
}}
position={[-0.01, -0.13, 0.15]}>
<boxGeometry args={[2, 1, 0.5]} />
<meshStandardMaterial transparent opacity={1} color={hoveredContent ? 'Yellow ' : getRandomColor()} />
</mesh>
<mesh geometry={nodes.Cube023.geometry} material={materials['Old Wooden Safe Box Wood 2.010']} />
<mesh geometry={nodes.Cube023_1.geometry} material={materials['Old Wooden Safe Box Wood 2.010']} />
<mesh
geometry={nodes.TorusOG.geometry}
material={materials['Old Wooden Safe Box Wood 2.011']}
position={[0.01, -0.13, 1.01]}
rotation={[Math.PI / 2, 0, 0]}
scale={[0.11, 0.03, 0.12]}
/>
<mesh
geometry={nodes.底座OG.geometry}
material={materials['Old Wooden Safe Box Wood 2.011']}
position={[0.01, -0.01, 1]}
rotation={[Math.PI / 2, 0, 0]}
scale={[0.09, 0.01, 0.09]}
/>
</group>
</group>
</group>
)
}
第一次點擊打開,再點一次關閉
onClick={(event) => click(!clicked)}
利用三元運算子 條件結果? A:B 的方式 更改抽屜的打開距離
lineH 則是前幾天利用陣列產生一堆小櫃子的變數
position={[-1.33, lineH, clicked ? 0.2 : -0.13]}